﻿// <copyright file="DataPoint.cs" company="Oleg V. Polikarpotchkin">
// Copyright © 2009 Oleg V. Polikarpotchkin. All Right Reserved
// </copyright>
// <author>Oleg V. Polikarpotchkin</author>
// <email>ov-p@yandex.ru</email>
// <date>2009-04-12</date>
// <summary>Classes to store Generic Data Points Series XML loaded.</summary>
// <revision>$Id$</revision>

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace OpenWPFChart.Helpers.XmlItemDataReader
{
	/// <summary>
	/// Describes the Generic Data Points Series single dimension.
	/// </summary>
	public struct Dimension
	{
		/// <summary>
		/// Gets the name of the dimension.
		/// </summary>
		/// <value>The name of the dimension or null.</value>
		public string Name { get; internal set; }

		/// <summary>
		/// Gets XML atomic type name like "double" or "gMonth".
		/// </summary>
		/// <value>XML atomic type name string.</value>
		/// <remarks>
		/// Type name string doesn't contains namespace prefix.
		/// </remarks>
		public string XsdTypeString { get; internal set; }

		/// <summary>
		/// Gets the CLR type.
		/// </summary>
		/// <value>The CLR type.</value>
		public Type ClrType
		{
			get;
			internal set;
		}

		/// <summary>
		/// Gets the "type string" assigned to this mapping like Double, Int, etc.
		/// </summary>
		/// <value>The type string.</value>
		/// <remarks>
		/// "Type string" is used in XML schema construction.
		/// </remarks>
		public string TypeString { get; internal set; }
	}

	/// <summary>
	/// Corresponds to the Generic Data Points Series XML element.
	/// </summary>
	public class DataPointSeries
	{
		public Dimension[] Dimensions { get; internal set; }

		/// <summary>
		/// Gets the ItemData type name.
		/// </summary>
		/// <value>ItemData type name.</value>
		public string ItemType { get; internal set; }

		Collection<string[]> xsdPoints = new Collection<string[]>();
		/// <summary>
		/// Gets the XML Points collection.
		/// </summary>
		/// <value>XML Points collection.</value>
		/// <remarks>
		/// String array item count must match the count of <see cref="Dimensions"/>.
		/// </remarks>
		public Collection<string[]> XsdPoints { get { return xsdPoints; } }

		/// <summary>
		/// Gets the Data Points sequence.
		/// </summary>
		/// <param name="converter">The XML->NET type converter.</param>
		/// <returns>The Data Points sequence</returns>
		/// <remarks>
		/// The x,y values of the <see cref="DataPoint"/> instance will be <c>null</c> if the
		/// XML->NET type conversion defined by the <see cref="Mapping"/> instance fails.
		/// </remarks>
		public IEnumerable<object[]> GetPoints(IXmlTypeConverter converter)
		{
			foreach (string[] xsdPoint in XsdPoints)
			{
				object[] dataPoint = new object[xsdPoint.Length];
				for (int i = 0; i < xsdPoint.Length; i++)
				{
					Dimension dim = Dimensions[i];
					try
					{
						dataPoint[i] = converter.Convert(dim.ClrType, dim.XsdTypeString, xsdPoint[i]);
					}
					catch (Exception) { }
				}
				yield return dataPoint;
			}
		}
		/// <summary>
		/// Gets the Data Points sequence using default converter.
		/// </summary>
		/// <returns>The Data Points sequence</returns>
		/// <remarks>
		/// The x,y values of the <see cref="DataPoint"/> instance will be <c>null</c> if the
		/// XML->NET type conversion defined by the <see cref="Mapping"/> instance fails.
		/// </remarks>
		public IEnumerable<object[]> GetPoints()
		{
			return GetPoints(new XmlTypeConverter());
		}
	}
}
